#pragma once
#include "State.h"
template <class entity_type>
class CStateMachine
{
public:
	CStateMachine(void);
	~CStateMachine(void);
	void Update()const;
	void RevertToPreviousState();

	CStateMachine(entity_type* owner):m_pOwner(owner),
		m_pCurrentState(NULL),
		m_pPreviousState(NULL),
		m_pGlobalState(NULL)
	{}

		//accessors
	CState<entity_type>*  CurrentState()  const{return m_pCurrentState;}
	CState<entity_type>*  GlobalState()   const{return m_pGlobalState;}
	CState<entity_type>*  PreviousState() const{return m_pPreviousState;}

	//use these methods to initialize the FSM
	void SetCurrentState(CState<entity_type>* s){m_pCurrentState = s;}
	void SetGlobalState(CState<entity_type>* s) {m_pGlobalState = s;}
	void SetPreviousState(CState<entity_type>* s){m_pPreviousState = s;}

	//returns true if the current state's type is equal to the type of the
	//class passed as a parameter.
	bool CStateMachine::isInState(const CState<entity_type>& st)const;

		//change to a new state
	void CStateMachine::ChangeState(CState<entity_type> *pNewState)
	{
		assert(pNewState &&
			"<StateMachine::ChangeState>: trying to change to a null state");
		//keep a record of the previous state
		m_pPreviousState = m_pCurrentState;

		//call the exit method of the existing state
		m_pCurrentState->Exit(m_pOwner);

		//change state to the new state
		m_pCurrentState = pNewState;

		//call the entry method of the new state
		m_pCurrentState->Enter(m_pOwner);
	}
private:

		//a pointer to the agent that owns this instance
	entity_type*          m_pOwner;

	CState<entity_type>*   m_pCurrentState;

	//a record of the last state the agent was in
	CState<entity_type>*   m_pPreviousState;

	//this state logic is called every time the FSM is updated
	CState<entity_type>*   m_pGlobalState;
};
